let app;

function getApp() {

    if (app) {
        app.logger.debug("already exists");
        return app;
    }

    const fs = require('fs');

    const Koa = require('koa');
    const parser = require("koa-bodyparser");
    const YAML = require('yaml');
    const json = require('./middleware/json');
    const logger = require('./middleware/logger');

    // 初始化mongodb
    const mongodbFunc = require('./mongodb/init');

    // 读取配置文件
    let file;
    try {
        file = fs.readFileSync("./config.yaml", "utf8");
    } catch (e) {
        console.error("read config file error!");
    }

    app = new Koa();

    // 注册日志
    logger(app);

    // 使用 koa-bodyparser 解析 post的数据，方便获取
    app.use(parser());

    const config = YAML.parse(file);
    if (!config) {
        app.logger.error("error loading config.");
        app.logger.debug("error loading config.");
    } else {
        app.config = config;
    }

    mongodbFunc(app);

    // 注册 json 转换中间件
    app.use(json());

    // 错误打印
    app.on("error", err => {
        app.logger.error('server error: ', err);
        app.logger.debug('server error: ', err)
    });

    // 访问日志记录
    app.use(async (ctx, next) => {
        const start = Date.now();
        return next().then(() => {
            const ms = Date.now() - start;
            const message = `${ctx.method} ${ctx.url} - ${ms} ms`;
            app.logger.info(message);
            app.logger.debug(message);
        });
    });

    // 错误处理
    app.use(async (ctx, next) => {
        try {
            await next();
        } catch (e) {
            app.logger.debug(e);
            app.logger.error(e);
            ctx.status = e.statusCode || e.status || 500;
            await ctx.json({
                message: e
            });
        }
    });

    // app.use(async ctx => {
    //     console.log(ctx);
    //     ctx.body = "ok"
    // });
    return app;

}

module.exports = getApp();
